package com.plian.system.service.fr.indicatorsvalue.impl;

import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.plian.Tools.*;
import com.plian.Tools.operation.OperationExpressionUtil;
import com.plian.Tools.pagedata.PageData;
import com.plian.system.constant.sys.FormStatusConstant;
import com.plian.system.dao.fr.gsalaryslip.GsalarySlipDao;
import com.plian.system.dto.fr.indicators.IndicatorsValueDTO;
import com.plian.system.entity.fr.indicators.GraphicOrgRelation;
import com.plian.system.entity.pm.property.PropertyBasics;
import com.plian.system.entity.sys.Org;
import com.plian.system.mapper.fr.indicators.IndicatorsValueMapper;
import com.plian.system.service.fr.bulletin.INewBulletinService;
import com.plian.system.service.fr.indicators.IComplexIndicatorsValueService;
import com.plian.system.service.fr.indicatorsvalue.IGraphicOrgRelationService;
import com.plian.system.service.fr.indicatorsvalue.IIndicatorsReportService;
import com.plian.system.service.pm.property.IPropertyBasicsService;
import com.plian.system.service.sys.orgzation.IOrgService;
import com.plian.system.service.zzd.helper.ZZDHelper;
import com.plian.system.vo.fr.indicatorsValue.IndicatorsReportVO;
import com.plian.system.vo.fr.indicatorsValue.IndicatorsValueVO;
import com.plian.system.vo.report.ChartsVO;
import com.plian.system.vo.report.SeriesVO;
import com.plian.system.vo.report.XAxisVO;
import com.plian.system.vo.zzd.finance.IndicatorsUnitDetailVO;
import com.plian.system.vo.zzd.finance.IndicatorsYearDataVO;
import com.plian.system.vo.zzd.finance.RevenueMonthDataVO;
import lombok.AllArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang.exception.ExceptionUtils;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.*;
import java.util.stream.Collectors;
import java.util.stream.Stream;

import static com.plian.system.constant.fr.IndicatorsCodeConstant.*;
import static java.util.stream.Collectors.reducing;

/**
 * @description:
 * @author: gangan
 * @create: 2022-05-12 14:07
 */
@Slf4j
@Service
@AllArgsConstructor
public class IndicatorsReportServiceImpl implements IIndicatorsReportService {

    private IndicatorsValueMapper indicatorsValueMapper;

    private IOrgService orgService;

    private IGraphicOrgRelationService graphicOrgRelationService;

    private GsalarySlipDao gsalarySlipDao;

    private IPropertyBasicsService propertyBasicsService;

    private INewBulletinService newBulletinService;

    private IComplexIndicatorsValueService complexIndicatorsValueService;

    private final static String MAX_MONTH = "12";

    private final static String SUM_MONTH = "00";

    @Override
    public List<IndicatorsReportVO> financialDataReport(IndicatorsValueDTO indicatorsValueDTO) {
        checkQueryParam(indicatorsValueDTO);
        indicatorsValueDTO.setCodes(Stream.of(K22, KLAST22, K30, KLAST30, K36,
                KLAST36, KLJ1, KLASTLJ1, KLJ19, KLASTLJ19).collect(Collectors.toList()));

        List<String> subtractParentList = graphicOrgRelationService.getSubtractParentList(indicatorsValueDTO.getCountDate());
        List<String> addParentList = graphicOrgRelationService.getAddParentList(indicatorsValueDTO.getCountDate());
        List<String> subtractChildList = new ArrayList<>();
        List<String> addChildList = new ArrayList<>();
        List<String> sumChildOrgIds = new ArrayList<>();
        handleOrgId(indicatorsValueDTO, subtractChildList, addChildList, sumChildOrgIds,
                subtractParentList, addParentList,  orgService.getDTFlag(indicatorsValueDTO.getCountDate()));

        indicatorsValueDTO.setCode(null);
        List<IndicatorsValueVO> valueVOS = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
        indicatorsValueDTO.setCodes(Stream.of(Y22, Y30, Y36, Y1, Y19).collect(Collectors.toList()));
        indicatorsValueDTO.setMonth("00");
        List<IndicatorsValueVO> budgetValueVOS = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
        if (CollectionUtil.isNotEmpty(budgetValueVOS)){
            valueVOS.addAll(budgetValueVOS);
        }
        PageData pd = new PageData();
        pd.put("year", indicatorsValueDTO.getYear());
        List<String> budgetUnitIds = new ArrayList<>();
        try {
            budgetUnitIds = gsalarySlipDao.findFillingGzwUnit(pd);
        }catch (Exception e){
            log.error(ExceptionUtils.getFullStackTrace(e));
        }


        Map<String, List<IndicatorsValueVO>> codeValueMap = valueVOS.stream().collect(Collectors.groupingBy(IndicatorsValueVO::getCode));
        List<IndicatorsReportVO> results = new ArrayList<>();
        results.add(getReportVO(K22, KLAST22, Y22, codeValueMap, sumChildOrgIds, subtractChildList, addChildList, budgetUnitIds));
        results.add(getReportVO(K30, KLAST30, Y30, codeValueMap, sumChildOrgIds, subtractChildList, addChildList, budgetUnitIds));
        results.add(getReportVO(K36, KLAST36, Y36, codeValueMap, sumChildOrgIds, subtractChildList, addChildList, budgetUnitIds));
        results.add(getReportVO(KLJ1, KLASTLJ1, Y1, codeValueMap, sumChildOrgIds, subtractChildList, addChildList, budgetUnitIds));
        results.add(getReportVO(KLJ19, KLASTLJ19, Y19, codeValueMap, sumChildOrgIds, subtractChildList, addChildList, budgetUnitIds));
        return results;
    }

//    @Override TODO DEL
//    public MainIndicatorsValueVO mainValueReport(PageData pd) {
//        IndicatorsValueDTO indicatorsValueDTO = new IndicatorsValueDTO();
//        indicatorsValueDTO.setCountDate(pd.getString("reportTime"));
//        indicatorsValueDTO.setOrgId(pd.getString("orgId"));
//        List<IndicatorsReportVO> dataList = financialDataReport(indicatorsValueDTO);
//        MainIndicatorsValueVO result = new MainIndicatorsValueVO();
//        if (CollectionUtil.isNotEmpty(dataList)){
//            for (IndicatorsReportVO indicatorsReportVO : dataList){
//                if (K22.equals(indicatorsReportVO.getCode())){
//                    result.setZCZE(BigDecimalUtil.toShortString(indicatorsReportVO.getValue(), 2));
//                    result.setZCZECompleteRate(indicatorsReportVO.getCompletion());
//                    result.setLastZCZE(indicatorsReportVO.getLastValue());
//                    result.setYsZCZE(indicatorsReportVO.getBudgetValue());
//                    result.setZCZERate(indicatorsReportVO.getGrowth());
//                }
//
//                if (K30.equals(indicatorsReportVO.getCode())){
//                    result.setFZZE(BigDecimalUtil.toShortString(indicatorsReportVO.getValue(), 2));
//                    result.setFZZECompleteRate(indicatorsReportVO.getCompletion());
//                    result.setLastFZZE(indicatorsReportVO.getLastValue());
//                    result.setYsFZZE(indicatorsReportVO.getBudgetValue());
//                    result.setFZZERate(indicatorsReportVO.getGrowth());
//                }
//
//                if (K36.equals(indicatorsReportVO.getCode())){
//                    result.setJZCZE(BigDecimalUtil.toShortString(indicatorsReportVO.getValue(), 2));
//                    result.setJZCZECompleteRate(indicatorsReportVO.getCompletion());
//                    result.setLastJZCZE(indicatorsReportVO.getLastValue());
//                    result.setYsJZCZE(indicatorsReportVO.getBudgetValue());
//                    result.setJZCZERate(indicatorsReportVO.getGrowth());
//                }
//
//                if (KLJ1.equals(indicatorsReportVO.getCode())){
//                    result.setYYSR(BigDecimalUtil.toShortString(indicatorsReportVO.getValue(), 2));
//                    result.setYYSRCompleteRate(indicatorsReportVO.getCompletion());
//                    result.setLastYYSR(indicatorsReportVO.getLastValue());
//                    result.setYsYYSR(indicatorsReportVO.getBudgetValue());
//                    result.setYYSRRate(indicatorsReportVO.getGrowth());
//                }
//
//                if (KLJ19.equals(indicatorsReportVO.getCode())){
//                    result.setLRZE(BigDecimalUtil.toShortString(indicatorsReportVO.getValue(), 2));
//                    result.setLRZECompleteRate(indicatorsReportVO.getCompletion());
//                    result.setLastLRZE(indicatorsReportVO.getLastValue());
//                    result.setYsLRZE(indicatorsReportVO.getBudgetValue());
//                    result.setLRZERate(indicatorsReportVO.getGrowth());
//                }
//            }
//        }
//        return result;
//    }

    @Override
    public ChartsVO singleIndicatorsReport(IndicatorsValueDTO indicatorsValueDTO) {
        checkQueryParam(indicatorsValueDTO);
        String code = indicatorsValueDTO.getCode();
        checkQueryCode(indicatorsValueDTO);

        List<String> subtractParentList = graphicOrgRelationService.getSubtractParentList(indicatorsValueDTO.getCountDate());
        List<String> addParentList = graphicOrgRelationService.getAddParentList(indicatorsValueDTO.getCountDate());
        List<String> subtractChildList = new ArrayList<>();
        List<String> addChildList = new ArrayList<>();
        List<String> sumChildOrgIds = new ArrayList<>();
        handleOrgId(indicatorsValueDTO, subtractChildList, addChildList, sumChildOrgIds,
                subtractParentList, addParentList, orgService.getDTFlag(indicatorsValueDTO.getCountDate()));

        List<IndicatorsValueVO> valueVOS = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
        XAxisVO xAxisVO = new XAxisVO();
        SeriesVO seriesVO = new SeriesVO();
        List<String> ids = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(valueVOS)){
            List<IndicatorsValueVO> dataList = valueVOS.stream().filter(indicatorsValueVO
                    -> sumChildOrgIds.contains(indicatorsValueVO.getOrgId())).collect(Collectors.toList());

            BigDecimal subtractValue = valueVOS.stream().filter(indicatorsValueVO
                    -> subtractChildList.contains(indicatorsValueVO.getOrgId()))
                    .map(IndicatorsValueVO::getValue)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            BigDecimal addValue = valueVOS.stream().filter(indicatorsValueVO
                    -> addChildList.contains(indicatorsValueVO.getOrgId()))
                    .map(IndicatorsValueVO::getValue)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            LinkedHashMap<String, IndicatorsValueVO> valueVOMap = new LinkedHashMap<>();
            for (IndicatorsValueVO valueVO : dataList){
                if (CollectionUtil.isNotEmpty(subtractParentList) && subtractParentList.contains(valueVO.getOrgId())){
                    valueVO.setValue(BigDecimalUtil.subtract(valueVO.getValue(), subtractValue));
                }
                if (CollectionUtil.isNotEmpty(addChildList) && addChildList.contains(valueVOS)){
                    valueVO.setValue(BigDecimalUtil.add(valueVO.getValue(), addValue));
                }
                valueVO.setValue(BigDecimalUtil.divide(valueVO.getValue(), new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP));

                if (valueVOMap.containsKey(valueVO.getOrgId())){
                    IndicatorsValueVO mapValueVO = valueVOMap.get(valueVO.getOrgId());
                    mapValueVO.setValue(BigDecimalUtil.add(mapValueVO.getValue(), valueVO.getValue()));
                }else {
                    valueVO.setCode(code);
                    valueVOMap.put(valueVO.getOrgId(), valueVO);
                }
            }

            if (sumChildOrgIds.size() > 1){
                //大于一个集团代表为国资委账号
                Map<String, List<GraphicOrgRelation>> mergeMap = graphicOrgRelationService.getMergeMap(indicatorsValueDTO.getCountDate());
                if (CollectionUtil.isNotEmpty(mergeMap)){
                    List<IndicatorsValueVO> removeVOList = new ArrayList<>();
                    for (String key : mergeMap.keySet()){
                        IndicatorsValueVO sumValueVO = new IndicatorsValueVO();
                        sumValueVO.setValue(new BigDecimal(0));
                        sumValueVO.setOrgId(key);
                        for (GraphicOrgRelation graphicOrgRelation : mergeMap.get(key)){
                            sumValueVO.setOrgName(graphicOrgRelation.getParentName());
                            if (valueVOMap.containsKey(graphicOrgRelation.getChildId())){
                                sumValueVO.setValue(BigDecimalUtil.add(sumValueVO.getValue(),
                                        valueVOMap.get(graphicOrgRelation.getChildId()).getValue()));
                                removeVOList.add(valueVOMap.get(graphicOrgRelation.getChildId()));
                            }
                        }
                        dataList.add(sumValueVO);
                    }

                    if (CollectionUtil.isNotEmpty(removeVOList)){
                        for (IndicatorsValueVO removeVO : removeVOList){
                            dataList.remove(removeVO);
                        }
                    }
                }
            }
            ids = dataList.stream().map(IndicatorsValueVO::getOrgId).collect(Collectors.toList());
            xAxisVO = XAxisVO.builder().data(valueVOMap.values().stream().map(valueVO ->
                StringUtil.isNotBlank(valueVO.getOrgShortName()) ? valueVO.getOrgShortName() : valueVO.getOrgName()).collect(Collectors.toList())).build();
            seriesVO = SeriesVO.builder().type("bar").data(valueVOMap.values().stream().map(IndicatorsValueVO::getValue).collect(Collectors.toList())).build();
        }

        return ChartsVO.builder().xAxis(Stream.of(xAxisVO).collect(Collectors.toList()))
                .ids(ids).series(Stream.of(seriesVO).collect(Collectors.toList())).build();
    }

//    @Override TODO DEL
//    public List<Object> singleIndicatorsThrough(IndicatorsValueDTO indicatorsValueDTO) {
//        String queryCode = indicatorsValueDTO.getCode();
//        checkQueryParam(indicatorsValueDTO);
//        checkQueryCode(indicatorsValueDTO);
//
//        List<String> subtractChildList = new ArrayList<>();
//        List<String> addChildList = new ArrayList<>();
//        List<String> sumChildOrgIds = new ArrayList<>();
//        List<String> subtractParentList = graphicOrgRelationService.getSubtractParentList(indicatorsValueDTO.getCountDate());
//        List<String> addParentList = graphicOrgRelationService.getAddParentList(indicatorsValueDTO.getCountDate());
//        handleOrgId(indicatorsValueDTO, subtractChildList, addChildList, sumChildOrgIds, subtractParentList,
//                addParentList, orgService.getDTFlag(indicatorsValueDTO.getCountDate()));
//
//        List<IndicatorsValueVO> dataList = indicatorsValueMapper.queryAllMonthGroupValueByCode(indicatorsValueDTO);
//        List<Object> results = new ArrayList<>();
//        if (CollectionUtil.isNotEmpty(dataList)){
//            Map<String, List<IndicatorsValueVO>> orgIdValueMap = dataList.stream()
//               .filter(valueVO -> sumChildOrgIds.contains(valueVO.getOrgId()))
//               .collect(Collectors.groupingBy(IndicatorsValueVO::getOrgId));
//            Map<String, IndicatorsValueVO> orgIdAndMonthValueMap = dataList.stream()
//                .collect(Collectors.toMap(valueVO -> valueVO.getOrgId() + StringPool.UNDERSCORE + valueVO.getMonth(), valueVO -> valueVO));
//            String queryMonth = indicatorsValueDTO.getMonth();
//            List<IndicatorsColorValueVO> colorValueList = new ArrayList<>();
//            Map<String, IndicatorsValueMonthVO> valueMonthVOMap = new HashMap<>();
//            Map<String, Org> orgMap = orgService.listByIds(sumChildOrgIds).stream().collect(Collectors.toMap(Org::getId, org -> org));
//
//            for (String orgId : orgIdValueMap.keySet()){
//                List<IndicatorsValueVO> list = orgIdValueMap.get(orgId);
//                //按月份排序
//                list.sort(Comparator.comparing(valueVO -> Integer.valueOf(valueVO.getMonth())));
//                List<String> valueList = new ArrayList<>();
//                List<BigDecimal> tempValueList = new ArrayList<>();
//                for (IndicatorsValueVO valueVO : list){
//                    String month = valueVO.getMonth();
//                    if (CollectionUtil.isNotEmpty(subtractParentList) && subtractParentList.contains(valueVO.getOrgId())){
//                        BigDecimal subtractValue = new BigDecimal(0);
//                        for (String subtractChildId : subtractChildList){
//                            String key = subtractChildId + StringPool.UNDERSCORE + month;
//                            if (orgIdAndMonthValueMap.containsKey(key)){
//                                subtractValue = BigDecimalUtil.add(orgIdAndMonthValueMap.get(key).getValue(), subtractValue);
//                            }
//                        }
//                        valueVO.setValue(BigDecimalUtil.subtract(valueVO.getValue(), subtractValue));
//                    }
//
//                    if (CollectionUtil.isNotEmpty(addParentList) && addParentList.contains(valueVO.getOrgId())){
//                        BigDecimal addValue = new BigDecimal(0);
//                        for (String addChildId : addChildList){
//                            String key = addChildId + StringPool.UNDERSCORE + valueVO.getMonth();
//                            if (orgIdAndMonthValueMap.containsKey(key)){
//                                addValue = BigDecimalUtil.add(orgIdAndMonthValueMap.get(key).getValue(), addValue);
//                            }
//                        }
//                        valueVO.setValue(BigDecimalUtil.add(valueVO.getValue(), addValue));
//                    }
//
//                    if (queryMonth.equals(month)){
//                        //当月值放入 colorValueList中
//                        IndicatorsColorValueVO colorValueVO = new IndicatorsColorValueVO();
//                        colorValueVO.setOrgId(valueVO.getOrgId());
//                        colorValueVO.setName(StringUtil.isNotBlank(valueVO.getOrgShortName()) ? valueVO.getOrgShortName() : valueVO.getOrgName());
//                        colorValueVO.setTempValue(valueVO.getValue());
//                        colorValueVO.setValue(BigDecimalUtil.toShortString(valueVO.getValue(), 2));
//                        if (orgMap.containsKey(valueVO.getOrgId())){
//                            colorValueVO.setOrderNumber(orgMap.get(valueVO.getOrgId()).getOrderNum());
//                        }
//                        colorValueList.add(colorValueVO);
//                    }
//                    tempValueList.add(valueVO.getValue());
//                    valueList.add(BigDecimalUtil.toShortString(valueVO.getValue(), 2));
//                }
//
//                IndicatorsValueMonthVO monthVO = new IndicatorsValueMonthVO();
//                monthVO.setOrgName(list.get(0).getOrgName());
//                monthVO.setOrgId(orgId);
//                monthVO.setValues(valueList);
//                monthVO.setTempValues(tempValueList);
//                valueMonthVOMap.put(orgId, monthVO);
//            }
//
//            if (sumChildOrgIds.size() > 1){
//                Map<String, IndicatorsColorValueVO> colorValueVOMap = colorValueList.stream()
//                        .collect(Collectors.toMap(colorValueVO -> colorValueVO.getOrgId(), colorValueVO -> colorValueVO));
//                //大于一个集团代表为国资委账号
//                Map<String, List<GraphicOrgRelation>> mergeMap = graphicOrgRelationService.getMergeMap(indicatorsValueDTO.getCountDate());
//                if (CollectionUtil.isNotEmpty(mergeMap)){
//                    //合并成一个节点 例如 城投城旅合并成城投
//                    List<IndicatorsColorValueVO> removeColorVOList = new ArrayList<>();
//                    for (String key : mergeMap.keySet()){
//                        IndicatorsColorValueVO sumColorValueVO = new IndicatorsColorValueVO();
//                        sumColorValueVO.setTempValue(new BigDecimal(0));
//                        sumColorValueVO.setOrgId(key);
//
//                        IndicatorsValueMonthVO sumValueMonthVO = new IndicatorsValueMonthVO();
//                        sumValueMonthVO.setOrgId(key);
//                        sumValueMonthVO.setOrgName(mergeMap.get(key).get(0).getParentName());
//                        List<BigDecimal> tempValueList = new ArrayList<>();
//                        for (GraphicOrgRelation graphicOrgRelation : mergeMap.get(key)){
//                            sumColorValueVO.setName(graphicOrgRelation.getParentName());
//                            if (colorValueVOMap.containsKey(graphicOrgRelation.getChildId())){
//                                sumColorValueVO.setTempValue(BigDecimalUtil.add(sumColorValueVO.getTempValue(),
//                                        colorValueVOMap.get(graphicOrgRelation.getChildId()).getTempValue()));
//                                sumColorValueVO.setValue(BigDecimalUtil.toShortString(sumColorValueVO.getTempValue(), 2));
//                                removeColorVOList.add(colorValueVOMap.get(graphicOrgRelation.getChildId()));
//                            }
//                            if (orgMap.containsKey(graphicOrgRelation.getChildId())){
//                                sumColorValueVO.setOrderNumber(orgMap.get(graphicOrgRelation.getChildId()).getOrderNum());
//                            }
//
//                            if (valueMonthVOMap.containsKey(graphicOrgRelation.getChildId())){
//                                List<BigDecimal> childTempValueList = valueMonthVOMap.get(graphicOrgRelation.getChildId()).getTempValues();
//                                for(int i = 0; i < childTempValueList.size(); i++){
//                                    BigDecimal childTempValue = childTempValueList.get(i);
//                                    if (tempValueList.size() == 0 || tempValueList.size() < i+1){
//                                        tempValueList.add(childTempValue);
//                                    }else {
//                                        BigDecimal tempValue = BigDecimalUtil.add(tempValueList.get(i), childTempValue);
//                                        tempValueList.remove(i);
//                                        tempValueList.add(i, tempValue);
//                                    }
//                                }
//                            }
//                        }
//                        sumValueMonthVO.setTempValues(tempValueList);
//                        colorValueList.add(sumColorValueVO);
//                        valueMonthVOMap.put(key, sumValueMonthVO);
//                    }
//
//                    if (CollectionUtil.isNotEmpty(removeColorVOList)){
//                        for (IndicatorsColorValueVO colorValueVO : removeColorVOList){
//                            colorValueList.remove(colorValueVO);
//                        }
//                    }
//                }
//            }
//
//            List<IndicatorsValueMonthVO> excelList = new ArrayList<>();
//            BigDecimal sumValue = new BigDecimal(0);
//            //设置颜色、排序、excelList和colorValueList排序一致
//            if (CollectionUtil.isNotEmpty(colorValueList)){
////                colorValueList = colorValueList.stream().filter(colorValueVO ->
////                        colorValueVO.getTempValue().compareTo(new BigDecimal(0)) != 0).collect(Collectors.toList());
//                colorValueList.sort(Comparator.comparing(IndicatorsColorValueVO::getOrderNumber));
//                Map<String, String> colorMap = getCompanyColorMap(colorValueList.stream()
//                        .map(IndicatorsColorValueVO::getOrgId).collect(Collectors.toList()));
//                for (IndicatorsColorValueVO colorValueVO : colorValueList){
//                    sumValue = BigDecimalUtil.add(sumValue, colorValueVO.getTempValue());
//                    colorValueVO.setColor(colorMap.get(colorValueVO.getOrgId()));
//                    colorValueVO.setTempValue(BigDecimalUtil.divide(colorValueVO.getTempValue(), new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP));
//                    colorValueVO.setValue(BigDecimalUtil.toShortString(colorValueVO.getTempValue(), 2));
//                    IndicatorsValueMonthVO valueMonthVO = valueMonthVOMap.get(colorValueVO.getOrgId());
//                    List<String> valueLis = new ArrayList<>();
//                    for (BigDecimal tempValue : valueMonthVO.getTempValues()){
//                        tempValue = BigDecimalUtil.divide(tempValue, new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP);
//                        valueLis.add(BigDecimalUtil.toShortString(tempValue, 2));
//                    }
//                    valueMonthVO.setValues(valueLis);
//                    excelList.add(valueMonthVO);
//                }
//                colorValueList.sort(Comparator.comparing(IndicatorsColorValueVO::getTempValue).reversed());
//            }
//
//            IndicatorsColorListVO indicatorsColorListVO = new IndicatorsColorListVO();
//            indicatorsColorListVO.setCode(queryCode);
//            indicatorsColorListVO.setSum(BigDecimalUtil.toShortString((BigDecimalUtil.divide(sumValue, new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP)), 2));
//            indicatorsColorListVO.setList(colorValueList);
//            Map<String, List<IndicatorsValueMonthVO>>  excelMap = new HashMap<>();
//            excelMap.put("excelList", excelList);
//            results.add(indicatorsColorListVO);
//            results.add(excelMap);
//
//        }
//        return results;
//    }

//    @Override TODO DEL
//    public PageData getGroupCodesVal(PageData pd) {
//        String reportTime = pd.getString("reportTime");
//        IndicatorsValueDTO indicatorsValueDTO = new IndicatorsValueDTO();
//        indicatorsValueDTO.setCountDate(reportTime);
//        indicatorsValueDTO.setOrgId(pd.getString("orgId"));
//        checkQueryParam(indicatorsValueDTO);
//        indicatorsValueDTO.setCodes(Stream.of(K22, K30, K36,
//                KLAST36, K58).collect(Collectors.toList()));
//
//        List<String> subtractParentList = graphicOrgRelationService.getSubtractParentList(reportTime);
//        List<String> addParentList = graphicOrgRelationService.getAddParentList(reportTime);
//        List<String> subtractChildList = new ArrayList<>();
//        List<String> addChildList = new ArrayList<>();
//        List<String> sumChildOrgIds = new ArrayList<>();
//        handleOrgId(indicatorsValueDTO, subtractChildList, addChildList, sumChildOrgIds,
//                subtractParentList, addParentList,  orgService.getDTFlag(indicatorsValueDTO.getCountDate()));
//
//        indicatorsValueDTO.setCode(null);
//        List<IndicatorsValueVO> valueVOS = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
//
//        PageData yearPd = new PageData();
//        pd.put("year", indicatorsValueDTO.getYear());
//        List<String> budgetUnitIds = new ArrayList<>();
//        try {
//            budgetUnitIds = gsalarySlipDao.findFillingGzwUnit(yearPd);
//        }catch (Exception e){
//            log.error(ExceptionUtils.getFullStackTrace(e));
//        }
//
//        Map<String, List<IndicatorsValueVO>> codeValueMap = valueVOS.stream().collect(Collectors.groupingBy(IndicatorsValueVO::getCode));
//
//        IndicatorsReportVO K22Report = getReportVO(K22, KLAST22, Y22, codeValueMap, sumChildOrgIds, subtractChildList, addChildList, budgetUnitIds);
//        IndicatorsReportVO K30Report = getReportVO(K30, KLAST30, Y30, codeValueMap, sumChildOrgIds, subtractChildList, addChildList, budgetUnitIds);
//        IndicatorsReportVO K36Report = getReportVO(K36, KLAST36, Y36, codeValueMap, sumChildOrgIds, subtractChildList, addChildList, budgetUnitIds);
//        IndicatorsReportVO K58Report = getReportVO(K58, KLAST58, Y1, codeValueMap, sumChildOrgIds, subtractChildList, addChildList, budgetUnitIds);
//        Map<String, List<IndicatorsValueVO>> maxLast36Map = new HashMap<>();
//        indicatorsValueDTO.setCodes(Stream.of(K36).collect(Collectors.toList()));
//        indicatorsValueDTO.setYear(String.valueOf(Integer.parseInt(reportTime.split(StringPool.DASH)[0]) - 1));
//        indicatorsValueDTO.setMonth(MAX_MONTH);
//        List<IndicatorsValueVO> last36List = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
//        maxLast36Map.put(KLAST36, last36List);
//        IndicatorsReportVO KLASTMAX36Report = getReportVO(KLAST36, null, null, maxLast36Map, sumChildOrgIds, subtractChildList, addChildList, budgetUnitIds);
//        BigDecimal ZCFZL = BigDecimalUtil.divide(K30Report.getValue(), K22Report.getValue(), 2, BigDecimal.ROUND_HALF_UP, 100);
//        BigDecimal K36b = K36Report.getValue().add(KLASTMAX36Report.getValue());
//        String month = pd.getString("reportTime").substring(5, 7);
//        BigDecimal JZCSYL = K58Report.getValue().divide(new BigDecimal(month),4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(12))
//                .divide(K36b,4,BigDecimal.ROUND_HALF_UP).multiply(new BigDecimal(2)).multiply(new BigDecimal("100"));
//        PageData resultDate = new PageData();
//        resultDate.put("ZCFZL", ZCFZL.toString());
//        resultDate.put("JZCSYL", JZCSYL.toString());
//        return resultDate;
//    }

    @Override
    public BigDecimal getNetAssets(List<String> orgIds, String reportTime) {
        if (CollectionUtil.isEmpty(orgIds)){
            return null;
        }
        IndicatorsValueDTO indicatorsValueDTO = new IndicatorsValueDTO();
        indicatorsValueDTO.setOrgIds(orgIds);
        String[] reportTimes = reportTime.split(StringPool.DASH);
        indicatorsValueDTO.setYear(reportTimes[0]);
        indicatorsValueDTO.setMonth(reportTimes[1]);
        indicatorsValueDTO.setCodes(Stream.of(K58, K36).collect(Collectors.toList()));
        List<IndicatorsValueVO> valueVOS = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
        Map<String, BigDecimal> codeValueMap = valueVOS.stream()
                .collect(Collectors.groupingBy(IndicatorsValueVO::getCode, reducing(BigDecimal.ZERO, IndicatorsValueVO::getValue, BigDecimal::add)));
        indicatorsValueDTO.setCodes(Stream.of(K36).collect(Collectors.toList()));
        indicatorsValueDTO.setYear(String.valueOf(Integer.parseInt(reportTimes[0]) - 1));
        indicatorsValueDTO.setMonth(MAX_MONTH);
        List<IndicatorsValueVO> last36List = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
        codeValueMap.put(KLAST36, last36List.stream().map(IndicatorsValueVO::getValue).reduce(BigDecimal.ZERO, BigDecimal::add));
        OperationExpressionUtil operationExpressionUtil = new OperationExpressionUtil();
        codeValueMap.put("month", new BigDecimal(reportTimes[1]));
        return new BigDecimal(operationExpressionUtil.operation(JZCSYL_FORMULA, codeValueMap, 2, BigDecimal.ROUND_HALF_UP));
    }

    @Override
    public BigDecimal getNetAssets(List<String> groupOrgIds, List<String> singleOrgIds, String reportTime) {
        List<IndicatorsValueVO> valueVOS = new ArrayList<>();
        IndicatorsValueDTO indicatorsValueDTO = new IndicatorsValueDTO();
        String[] reportTimes = reportTime.split(StringPool.DASH);
        indicatorsValueDTO.setYear(reportTimes[0]);
        indicatorsValueDTO.setMonth(reportTimes[1]);
        indicatorsValueDTO.setCodes(Stream.of(K58, K36).collect(Collectors.toList()));
        if (CollectionUtil.isNotEmpty(groupOrgIds)){
            indicatorsValueDTO.setOrgIds(groupOrgIds);
            valueVOS.addAll(indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO));
        }
        if (CollectionUtil.isNotEmpty(singleOrgIds)){
            indicatorsValueDTO.setOrgIds(singleOrgIds);
            valueVOS.addAll(indicatorsValueMapper.querySingleValueByCode(indicatorsValueDTO));
        }
        Map<String, BigDecimal> codeValueMap = valueVOS.stream()
                .collect(Collectors.groupingBy(IndicatorsValueVO::getCode, reducing(BigDecimal.ZERO, IndicatorsValueVO::getValue, BigDecimal::add)));
        indicatorsValueDTO.setCodes(Stream.of(K36).collect(Collectors.toList()));
        indicatorsValueDTO.setYear(String.valueOf(Integer.parseInt(reportTimes[0]) - 1));
        indicatorsValueDTO.setMonth(MAX_MONTH);
        List<IndicatorsValueVO> last36List = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(groupOrgIds)){
            indicatorsValueDTO.setOrgIds(groupOrgIds);
            last36List.addAll(indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO));
        }
        if (CollectionUtil.isNotEmpty(singleOrgIds)){
            indicatorsValueDTO.setOrgIds(singleOrgIds);
            last36List.addAll(indicatorsValueMapper.querySingleValueByCode(indicatorsValueDTO));
        }
        codeValueMap.put(KLAST36, last36List.stream().map(IndicatorsValueVO::getValue).reduce(BigDecimal.ZERO, BigDecimal::add));
        OperationExpressionUtil operationExpressionUtil = new OperationExpressionUtil();
        codeValueMap.put("month", new BigDecimal(reportTimes[1]));
        return new BigDecimal(operationExpressionUtil.operation(JZCSYL_FORMULA, codeValueMap, 2, BigDecimal.ROUND_HALF_UP));
    }

    @Override
    public List<IndicatorsUnitDetailVO> getGroupNetAssets(List<String> orgIds, String reportTime) {
        if (CollectionUtil.isEmpty(orgIds)){
            return new ArrayList<>();
        }
        IndicatorsValueDTO indicatorsValueDTO = new IndicatorsValueDTO();
        indicatorsValueDTO.setOrgIds(orgIds);
        String[] reportTimes = reportTime.split(StringPool.DASH);
        indicatorsValueDTO.setYear(reportTimes[0]);
        indicatorsValueDTO.setMonth(reportTimes[1]);
        indicatorsValueDTO.setCodes(Stream.of(K58, K36).collect(Collectors.toList()));
        List<IndicatorsValueVO> valueVOS = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
        if (CollectionUtil.isEmpty(valueVOS)){
            return new ArrayList<>();
        }
        Map<String, List<IndicatorsValueVO>> orgIdValueMap = valueVOS.stream()
                .collect(Collectors.groupingBy(IndicatorsValueVO::getOrgId));
        indicatorsValueDTO.setCodes(Stream.of(K36).collect(Collectors.toList()));
        indicatorsValueDTO.setYear(String.valueOf(Integer.parseInt(reportTimes[0]) - 1));
        indicatorsValueDTO.setMonth(MAX_MONTH);
        List<IndicatorsValueVO> last36List = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
        Map<String, IndicatorsValueVO> orgIdKLast36ValueMap = last36List.stream()
                .collect(Collectors.toMap(IndicatorsValueVO::getOrgId, valueVO -> valueVO));
        OperationExpressionUtil operationExpressionUtil = new OperationExpressionUtil();
        List<IndicatorsUnitDetailVO> results = new ArrayList<>();
        for (String orgId : orgIds){
            Map<String, BigDecimal> codeValueMap = new HashMap<>();
            codeValueMap.put(K58, orgIdValueMap.get(orgId).stream().filter(valueVO -> valueVO.getCode().equals(K58))
                    .map(IndicatorsValueVO::getValue).reduce(BigDecimal.ZERO, BigDecimal::add));
            codeValueMap.put(K36, orgIdValueMap.get(orgId).stream().filter(valueVO -> valueVO.getCode().equals(K36))
                    .map(IndicatorsValueVO::getValue).reduce(BigDecimal.ZERO, BigDecimal::add));
            IndicatorsValueVO kLast36ValueVO = orgIdKLast36ValueMap.get(orgId);
            codeValueMap.put(KLAST36, kLast36ValueVO.getValue());
            codeValueMap.put("month", new BigDecimal(reportTimes[1]));
            IndicatorsUnitDetailVO detail = new IndicatorsUnitDetailVO();
            detail.setUnitId(orgId);
            detail.setUnitName(StringUtil.isNotBlank(kLast36ValueVO.getOrgShortName()) ? kLast36ValueVO.getOrgShortName() : kLast36ValueVO.getOrgName());
            detail.setValue(new BigDecimal(operationExpressionUtil.operation(JZCSYL_FORMULA, codeValueMap, 2, BigDecimal.ROUND_HALF_UP)));
            results.add(detail);
        }

        return results;
    }

    @Override
    public List<IndicatorsUnitDetailVO> getAllNetAssets(List<String> groupOrgIds, List<String> singleOrgIds, String reportTime) {
        IndicatorsValueDTO indicatorsValueDTO = new IndicatorsValueDTO();

        String[] reportTimes = reportTime.split(StringPool.DASH);
        indicatorsValueDTO.setYear(reportTimes[0]);
        indicatorsValueDTO.setMonth(reportTimes[1]);
        indicatorsValueDTO.setCodes(Stream.of(K58, K36).collect(Collectors.toList()));
        //合并组织净资产收益率
        List<IndicatorsValueVO> valueVOS = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(groupOrgIds)){
            indicatorsValueDTO.setOrgIds(groupOrgIds);
            valueVOS.addAll(indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO));
        }
        if (CollectionUtil.isNotEmpty(singleOrgIds)){
            indicatorsValueDTO.setOrgIds(singleOrgIds);
            valueVOS.addAll(indicatorsValueMapper.querySingleValueByCode(indicatorsValueDTO));
        }
        if (CollectionUtil.isEmpty(valueVOS)){
            return new ArrayList<>();
        }
        Map<String, List<IndicatorsValueVO>> orgIdValueMap = valueVOS.stream()
                .collect(Collectors.groupingBy(IndicatorsValueVO::getOrgId));
        indicatorsValueDTO.setCodes(Stream.of(K36).collect(Collectors.toList()));
        indicatorsValueDTO.setYear(String.valueOf(Integer.parseInt(reportTimes[0]) - 1));
        indicatorsValueDTO.setMonth(MAX_MONTH);
        indicatorsValueDTO.setOrgIds(groupOrgIds);
        List<IndicatorsValueVO> last36List = new ArrayList<>();
        if (CollectionUtil.isNotEmpty(groupOrgIds)){
            indicatorsValueDTO.setOrgIds(groupOrgIds);
            last36List.addAll(indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO));
        }
        if (CollectionUtil.isNotEmpty(singleOrgIds)){
            indicatorsValueDTO.setOrgIds(singleOrgIds);
            last36List.addAll(indicatorsValueMapper.querySingleValueByCode(indicatorsValueDTO));
        }
        Map<String, IndicatorsValueVO> orgIdKLast36ValueMap = last36List.stream()
                .collect(Collectors.toMap(IndicatorsValueVO::getOrgId, valueVO -> valueVO));
        OperationExpressionUtil operationExpressionUtil = new OperationExpressionUtil();
        List<String> allOrgIds = Stream.concat(groupOrgIds.stream(),singleOrgIds.stream()).collect(Collectors.toList());
        List<IndicatorsUnitDetailVO> results = new ArrayList<>();
        for (String orgId : allOrgIds){
            Map<String, BigDecimal> codeValueMap = new HashMap<>();
            List<IndicatorsValueVO> indicatorsValueVOS = orgIdValueMap.get(orgId);
            if (CollectionUtil.isNotEmpty(indicatorsValueVOS)){
                codeValueMap.put(K58, indicatorsValueVOS.stream().filter(valueVO -> valueVO.getCode().equals(K58) )
                        .map(IndicatorsValueVO::getValue).filter(m -> Optional.ofNullable(m).isPresent()).reduce(BigDecimal.ZERO, BigDecimal::add));
                codeValueMap.put(K36, indicatorsValueVOS.stream().filter(valueVO -> valueVO.getCode().equals(K36))
                        .map(IndicatorsValueVO::getValue).filter(m -> Optional.ofNullable(m).isPresent()).reduce(BigDecimal.ZERO, BigDecimal::add));
                IndicatorsValueVO kLast36ValueVO = orgIdKLast36ValueMap.get(orgId);
                if (Optional.ofNullable(kLast36ValueVO).isPresent()){
                    codeValueMap.put(KLAST36, kLast36ValueVO.getValue());
                    codeValueMap.put("month", new BigDecimal(reportTimes[1]));
                    IndicatorsUnitDetailVO detail = new IndicatorsUnitDetailVO();
                    detail.setUnitId(orgId);
                    detail.setUnitName(StringUtil.isNotBlank(kLast36ValueVO.getOrgShortName()) ? kLast36ValueVO.getOrgShortName() : kLast36ValueVO.getOrgName());
                    detail.setUnitAllName( kLast36ValueVO.getOrgName());
                    detail.setValue(new BigDecimal(operationExpressionUtil.operation(JZCSYL_FORMULA, codeValueMap, 2, BigDecimal.ROUND_HALF_UP)));
                    results.add(detail);
                }
            }
        }

        return results;
    }

    @Override
    public IndicatorsReportVO getNetAssetsReport(List<String> groupIds, String reportTime) {
        return  IndicatorsReportVO.builder().value(getNetAssets(groupIds, reportTime))
                .codeName(JZCSYL_NAME).code(JZCSYL)
                .completion(StringPool.DASH).growth(StringPool.DASH).build();
    }

    /**
     * 给每个集团赋予颜色
     * @param orgIds
     * @return
     */
    private Map<String, String> getCompanyColorMap(List<String> orgIds){
        Map<String, String> colorMap = new HashMap<>();
        List<String> colors = new ArrayList<>();
        colors.add("#842C3C");
        colors.add("#B82C35");
        colors.add("#EA2627");
        colors.add("#ED8689");
        colors.add("#008B8B");
        colors.add("#EF9D6E");
        colors.add("#EED56E");
        colors.add("#59DBDB");
        colors.add("#01A2CE");
        colors.add("#E9967A");
        colors.add("#43DAA3");
        colors.add("#04A68F");
        colors.add("#7792AF");
        colors.add("#B6C4D1");
        colors.add("#FF7F50");
        colors.add("#6495ED");
        colors.add("#FFC0CB");
        colors.add("#FFD700");
        colors.add("#FFA500");
        colors.add("#FFDEAD");

        if (CollectionUtil.isNotEmpty(orgIds)){
            for (int i = 0; i < orgIds.size(); i++){
                if (i < colors.size()){
                    colorMap.put(orgIds.get(i), colors.get(i));
                }else {
                    colorMap.put(orgIds.get(i), "");
                }
            }

        }
        return colorMap;
    }

    private void checkQueryCode(IndicatorsValueDTO indicatorsValueDTO){
        if (StringUtil.isBlank(indicatorsValueDTO.getCode())){
            throw new RuntimeException("code为空");
        }
        if (KLSZE.equals(indicatorsValueDTO.getCode())){
            indicatorsValueDTO.setCodes(Stream.of(KSUM40, K58).collect(Collectors.toList()));
            indicatorsValueDTO.setCode(null);
        }
    }

    /**
     * 基本查询条件设置
     * @param indicatorsValueDTO
     */
    private void checkQueryParam(IndicatorsValueDTO indicatorsValueDTO){
        if(StringUtil.isBlank(indicatorsValueDTO.getCountDate())){
            indicatorsValueDTO.setCountDate(DateUtil.format(DateUtil.now(), DateUtil.PATTERN_MONTH));
        }
        String[] strings = indicatorsValueDTO.getCountDate().split(StringPool.DASH);
        indicatorsValueDTO.setYear(strings[0]);
        indicatorsValueDTO.setMonth(strings[1]);
        if (StringUtil.isBlank(indicatorsValueDTO.getOrgId())){
            indicatorsValueDTO.setOrgId(TokenUtil.getTokenOrgId());
        }
    }

    /**
     * 相关id处理
     * @param indicatorsValueDTO
     * @param subtractChildList
     * @param addChildList
     * @param sumChildOrgIds
     */
    private void handleOrgId(IndicatorsValueDTO indicatorsValueDTO, List<String> subtractChildList,
                               List<String> addChildList, List<String> sumChildOrgIds, List<String> subtractParentList,
                             List<String> addParentList, boolean dtFlag){

        List<String> orgIds = new ArrayList<>();
        if (orgService.checkIsGzw(indicatorsValueDTO.getOrgId())){
            sumChildOrgIds.addAll(orgService.getGzwUnits(dtFlag)
                    .stream().map(Org::getId).collect(Collectors.toList()));
            orgIds.addAll(sumChildOrgIds);
            List<String> tempSubList = graphicOrgRelationService.getSubtractChildList(indicatorsValueDTO.getCountDate());
            if (CollectionUtil.isNotEmpty(tempSubList)){
                subtractChildList.addAll(tempSubList);
                orgIds.addAll(tempSubList);
            }
            List<String> tempAddList = graphicOrgRelationService.getAddChildList(indicatorsValueDTO.getCountDate());
            if (CollectionUtil.isNotEmpty(tempAddList)){
                addChildList.addAll(tempAddList);
                orgIds.addAll(tempAddList);
            }
            indicatorsValueDTO.setOrgId(null);
            indicatorsValueDTO.setOrgIds(orgIds);
        }else {
            String orgId = indicatorsValueDTO.getOrgId();
            if ((CollectionUtil.isNotEmpty(subtractParentList) &&
                    subtractParentList.contains(orgId))){
                List<String> tempSubList = graphicOrgRelationService.getSubtractChildList(indicatorsValueDTO.getCountDate());
                if (CollectionUtil.isNotEmpty(tempSubList)){
                    subtractChildList.addAll(tempSubList);
                    orgIds.add(indicatorsValueDTO.getOrgId());
                    orgIds.addAll(tempSubList);
                    indicatorsValueDTO.setOrgId(null);
                    indicatorsValueDTO.setOrgIds(orgIds);
                }
            }
            if ((CollectionUtil.isNotEmpty(addParentList) &&
                    addParentList.contains(orgId))){
                List<String> tempAddList = graphicOrgRelationService.getAddChildList(indicatorsValueDTO.getCountDate());
                if (CollectionUtil.isNotEmpty(tempAddList)){
                    addChildList.addAll(tempAddList);
                    orgIds.add(indicatorsValueDTO.getOrgId());
                    orgIds.addAll(tempAddList);
                    indicatorsValueDTO.setOrgId(null);
                    indicatorsValueDTO.setOrgIds(orgIds);
                }
            }
            sumChildOrgIds.add(orgId);
        }


        if (CollectionUtil.isEmpty(sumChildOrgIds)){
            sumChildOrgIds.add(indicatorsValueDTO.getOrgId());
        }
    }

    private IndicatorsReportVO getReportVO(String valueCode, String lastValueCode, String budgetValueCode,
                                     Map<String, List<IndicatorsValueVO>> codeValueMap, List<String> sumChildOrgIds,
                                           List<String> subtractChildList, List<String> addChildList, List<String> budgetUnitIds){
        IndicatorsReportVO indicatorsReportVO = new IndicatorsReportVO();
        indicatorsReportVO.setCode(valueCode);
        BigDecimal value = new BigDecimal(0);
        BigDecimal lastValue = new BigDecimal(0);
        BigDecimal budgetValue = new BigDecimal(0);
        BigDecimal completeValue = new BigDecimal(0);
        if (codeValueMap.containsKey(valueCode)){
            value = sumValue(valueCode, value, codeValueMap, sumChildOrgIds, subtractChildList, addChildList);
            if (CollectionUtil.isNotEmpty(budgetUnitIds)){
                completeValue = sumValue(valueCode, completeValue, codeValueMap, budgetUnitIds, subtractChildList, addChildList);
            }
        }
        if (codeValueMap.containsKey(lastValueCode)){
            lastValue = sumValue(lastValueCode, lastValue, codeValueMap, sumChildOrgIds, subtractChildList, addChildList);
        }
        if (codeValueMap.containsKey(budgetValueCode)){
            budgetValue = codeValueMap.get(budgetValueCode).stream().filter(indicatorsValueVO
                    -> sumChildOrgIds.contains(indicatorsValueVO.getOrgId()))
                    .map(IndicatorsValueVO::getValue)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);

        }
        indicatorsReportVO.setGrowth(StringPool.DASH + StringPool.DASH);
        BigDecimal growth = BigDecimalUtil.divide(value, lastValue, 4, BigDecimal.ROUND_HALF_UP, 100);

        if (value.compareTo(new BigDecimal(0)) != 0 && growth != null){
            if (lastValue.compareTo(new BigDecimal(0)) == -1){
                growth = BigDecimalUtil.subtract(new BigDecimal(100), growth);
            }else {
                growth = BigDecimalUtil.subtract(growth, new BigDecimal(100));
            }
            indicatorsReportVO.setGrowth(BigDecimalUtil.toShortString(growth, 2));
        }

        indicatorsReportVO.setCompletion(StringPool.DASH);
        BigDecimal completion = BigDecimalUtil.divide(completeValue, budgetValue, 4, BigDecimal.ROUND_HALF_UP, 100);
        if (value.compareTo(new BigDecimal(0)) == 1 && completion != null){
            indicatorsReportVO.setCompletion(BigDecimalUtil.toShortString(completion, 2));
        }
        indicatorsReportVO.setValue(BigDecimalUtil.divide(value, new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP));
        indicatorsReportVO.setLastValue(BigDecimalUtil.divide(lastValue, new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP));
        indicatorsReportVO.setBudgetValue(BigDecimalUtil.divide(budgetValue, new BigDecimal(10000), 2, BigDecimal.ROUND_HALF_UP));
        return indicatorsReportVO;
    }

    private BigDecimal sumValue(String code, BigDecimal value, Map<String, List<IndicatorsValueVO>> codeValueMap,
                          List<String> sumChildOrgIds, List<String> subtractChildList, List<String> addChildList){
        value = codeValueMap.get(code).stream().filter(indicatorsValueVO
                -> sumChildOrgIds.contains(indicatorsValueVO.getOrgId()))
                .map(IndicatorsValueVO::getValue)
                .reduce(BigDecimal.ZERO, BigDecimal::add);
        value = valueSubtract(code, value, codeValueMap, subtractChildList);
        value = valueAdd(code, value, codeValueMap, addChildList);
        return value;
    }

    private BigDecimal valueSubtract(String code, BigDecimal value, Map<String, List<IndicatorsValueVO>> codeValueMap, List<String> subtractChildList){
        if (CollectionUtil.isNotEmpty(subtractChildList)){
            BigDecimal subtractValue = codeValueMap.get(code).stream().filter(indicatorsValueVO
                    -> subtractChildList.contains(indicatorsValueVO.getOrgId()))
                    .map(IndicatorsValueVO::getValue)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            value = BigDecimalUtil.subtract(value, subtractValue);
        }
        return value;
    }

    private BigDecimal valueAdd(String code, BigDecimal value, Map<String, List<IndicatorsValueVO>> codeValueMap, List<String> addChildList){
        if (CollectionUtil.isNotEmpty(addChildList)){
            BigDecimal addValue = codeValueMap.get(code).stream().filter(indicatorsValueVO
                    -> addChildList.contains(indicatorsValueVO.getOrgId()))
                    .map(IndicatorsValueVO::getValue)
                    .reduce(BigDecimal.ZERO, BigDecimal::add);
            value = BigDecimalUtil.add(value, addValue);
        }
        return value;
    }

    private void handleOrgId(String orgId, IndicatorsValueDTO indicatorsValueDTO,
                             List<String> subtractChildList, List<String> addChildList, List<String> sumChildOrgIds) {
        List<String> orgIds = new ArrayList<>();
        sumChildOrgIds.add(orgId);
        orgIds.addAll(sumChildOrgIds);
        List<String> tempSubList = graphicOrgRelationService.getSubtract(orgId);
        if (CollectionUtil.isNotEmpty(tempSubList)) {
            subtractChildList.addAll(tempSubList);
            orgIds.addAll(tempSubList);
        }
        List<String> tempAddList = graphicOrgRelationService.getAdd(orgId);
        if (CollectionUtil.isNotEmpty(tempAddList)) {
            addChildList.addAll(tempAddList);
            orgIds.addAll(tempAddList);
        }
        indicatorsValueDTO.setOrgIds(orgIds);
    }


    @Override
    public IndicatorsYearDataVO getIndicatorsYearData(String propertyId, String code, String reportTime) {
        PropertyBasics propertyBasics = propertyBasicsService.getOne(Wrappers.<PropertyBasics>lambdaQuery()
                .eq(PropertyBasics::getId, propertyId)
                .eq(PropertyBasics::getStatus, FormStatusConstant.FINISH));
        if (propertyBasics == null || StringUtil.isBlank(propertyBasics.getOrgId())){
            return null;
        }

        List<String> subtractChildList = new ArrayList<>();
        List<String> addChildList = new ArrayList<>();
        List<String> sumChildOrgIds = new ArrayList<>();

        IndicatorsValueDTO indicatorsValueDTO = new IndicatorsValueDTO();
        if (StringUtil.isBlank(reportTime)) {
            reportTime = newBulletinService.getMaxReportTimeByOrgId(propertyBasics.getOrgId());
        }
        handleOrgId(propertyBasics.getOrgId(), indicatorsValueDTO, subtractChildList, addChildList, sumChildOrgIds);
        String[] reportTimes = reportTime.split(StringPool.DASH);
        int year = Integer.valueOf(reportTimes[0]);
        List<String> yearList = new ArrayList<>();
        List<BigDecimal> valueList = new ArrayList<>();
        indicatorsValueDTO.setCodes(Stream.of(code).collect(Collectors.toList()));
        for (int i = year - 4; i < year; i++) {
            String yearStr = String.valueOf(i);
            yearList.add(yearStr);
            indicatorsValueDTO.setYear(yearStr);
            indicatorsValueDTO.setMonth(MAX_MONTH);
            List<IndicatorsValueVO> valueVOS = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
            if (CollectionUtil.isNotEmpty(valueVOS)) {
                //对valueVOS的value进行合计
                Map<String, BigDecimal> codeValueMap = ZZDHelper
                        .indicatorsValueToValueMap(year, valueVOS, subtractChildList, addChildList, sumChildOrgIds);
                BigDecimal bigDecimal = BigDecimalUtil.divide(codeValueMap.get(code), BigDecimal.valueOf(10000), 2, BigDecimal.ROUND_HALF_UP);
                valueList.add(bigDecimal);
            } else {
                valueList.add(null);
            }
        }
        indicatorsValueDTO.setYear(reportTimes[0]);
        indicatorsValueDTO.setMonth(reportTimes[1]);
        List<IndicatorsValueVO> valueVOS = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
        yearList.add(reportTimes[0]);
        if (CollectionUtil.isNotEmpty(valueVOS)) {
            Map<String, BigDecimal> codeValueMap = ZZDHelper
                    .indicatorsValueToValueMap(Integer.parseInt(reportTimes[0]), valueVOS, subtractChildList, addChildList, sumChildOrgIds);
            BigDecimal bigDecimal = BigDecimalUtil.divide(codeValueMap.get(code), BigDecimal.valueOf(10000), 2, BigDecimal.ROUND_HALF_UP);
            valueList.add(bigDecimal);
        } else {
            valueList.add(null);
        }
        return IndicatorsYearDataVO.builder().yearList(yearList).valueList(valueList).build();
    }

    @Override
    public List<IndicatorsReportVO> getAssetIndicators(String propertyId, String reportTime) {
        PropertyBasics propertyBasics = propertyBasicsService.getOne(Wrappers.<PropertyBasics>lambdaQuery()
                .eq(PropertyBasics::getId, propertyId)
                .eq(PropertyBasics::getStatus, FormStatusConstant.FINISH));
        if (propertyBasics == null || StringUtil.isBlank(propertyBasics.getOrgId())){
            return null;
        }
        List<String> subtractChildList = new ArrayList<>();
        List<String> addChildList = new ArrayList<>();
        List<String> sumChildOrgIds = new ArrayList<>();

        IndicatorsValueDTO indicatorsValueDTO = new IndicatorsValueDTO();
        if (StringUtil.isBlank(reportTime)) {
            reportTime = newBulletinService.getMaxReportTimeByOrgId(propertyBasics.getOrgId());
        }
        handleOrgId(propertyBasics.getOrgId(), indicatorsValueDTO, subtractChildList, addChildList, sumChildOrgIds);
        String[] reportTimes = reportTime.split(StringPool.DASH);
        indicatorsValueDTO.setYear(reportTimes[0]);
        indicatorsValueDTO.setMonth(reportTimes[1]);
        indicatorsValueDTO.setCodes(Stream.of(K22, KLAST22, K30, KLAST30, K36, KLAST36, K33, KLAST33).collect(Collectors.toList()));
        List<IndicatorsValueVO> valueVOS = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
        //  对valueVOS按code分组，对value合计
        Map<String, BigDecimal> codeValueMap = ZZDHelper
                .indicatorsValueToValueMap(Integer.valueOf(reportTimes[0]), valueVOS, subtractChildList, addChildList, sumChildOrgIds);
        indicatorsValueDTO.setCodes(Stream.of(Y22, Y30, Y36, Y33).collect(Collectors.toList()));
        indicatorsValueDTO.setMonth(SUM_MONTH);
        List<IndicatorsValueVO> budgetValueVOS = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
        codeValueMap.putAll(budgetValueVOS.stream()
                .collect(Collectors.groupingBy(IndicatorsValueVO::getCode, reducing(BigDecimal.ZERO, IndicatorsValueVO::getValue, BigDecimal::add))));
        return Stream.of(ZZDHelper.getReportVO(K22, KLAST22, Y22, K22_NAME, codeValueMap),
                ZZDHelper.getReportVO(K36, KLAST36, Y36, K36_NAME, codeValueMap),
                ZZDHelper.getReportVO(K30, KLAST30, Y30, K30_NAME, codeValueMap),
                ZZDHelper.getReportVO(K33, KLAST33, Y33, K33_NAME, codeValueMap)).collect(Collectors.toList());
    }

    @Override
    public List<IndicatorsReportVO> getOperatingIndicators(String propertyId, String reportTime) {
        PropertyBasics propertyBasics = propertyBasicsService.getOne(Wrappers.<PropertyBasics>lambdaQuery()
                .eq(PropertyBasics::getId, propertyId)
                .eq(PropertyBasics::getStatus, FormStatusConstant.FINISH));
        if (propertyBasics == null || StringUtil.isBlank(propertyBasics.getOrgId())){
            return null;
        }
        List<String> subtractChildList = new ArrayList<>();
        List<String> addChildList = new ArrayList<>();
        List<String> sumChildOrgIds = new ArrayList<>();

        IndicatorsValueDTO indicatorsValueDTO = new IndicatorsValueDTO();
        if (StringUtil.isBlank(reportTime)) {
            reportTime = newBulletinService.getMaxReportTimeByOrgId(propertyBasics.getOrgId());
        }
        handleOrgId(propertyBasics.getOrgId(), indicatorsValueDTO, subtractChildList, addChildList, sumChildOrgIds);
        String[] reportTimes = reportTime.split(StringPool.DASH);
        indicatorsValueDTO.setYear(reportTimes[0]);
        indicatorsValueDTO.setMonth(reportTimes[1]);
        indicatorsValueDTO.setCodes(Stream.of(KLJ1, KLASTLJ1, KLJ19, KLASTLJ19, KSUM40, KLAST40, K58, KLAST58).collect(Collectors.toList()));
        List<IndicatorsValueVO> valueVOS = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
        //  对valueVOS按code分组，对value合计
        Map<String, BigDecimal> codeValueMap = ZZDHelper
                .indicatorsValueToValueMap(Integer.valueOf(reportTimes[0]), valueVOS, subtractChildList, addChildList, sumChildOrgIds);
        indicatorsValueDTO.setCodes(Stream.of(Y1, Y19, Y20).collect(Collectors.toList()));
        indicatorsValueDTO.setMonth("00");
        List<IndicatorsValueVO> budgetValueVOS = indicatorsValueMapper.queryGroupValueByCode(indicatorsValueDTO);
        codeValueMap.putAll(budgetValueVOS.stream()
                .collect(Collectors.groupingBy(IndicatorsValueVO::getCode, reducing(BigDecimal.ZERO, IndicatorsValueVO::getValue, BigDecimal::add))));
        return Stream.of(ZZDHelper.getReportVO(KLJ1, KLASTLJ1, Y1, KLJ1_NAME, codeValueMap),
                ZZDHelper.getReportVO(KLJ19, KLASTLJ19, Y19, KLJ19_NAME, codeValueMap),
                ZZDHelper.getReportVO(K58, KLAST58, Y20, K58_NAME, codeValueMap),
                ZZDHelper.getReportVO(TOTAL_PROFIT_TAX, Stream.of(KSUM40, K58).collect(Collectors.toList()),
                        Stream.of(KLAST40, KLAST58).collect(Collectors.toList()), null, TOTAL_PROFIT_TAX_NAME, codeValueMap)).collect(Collectors.toList());
    }

    @Override
    public RevenueMonthDataVO getYearRevenue(String propertyId, String reportTime) {
        PropertyBasics propertyBasics = propertyBasicsService.getOne(Wrappers.<PropertyBasics>lambdaQuery()
                .eq(PropertyBasics::getId, propertyId)
                .eq(PropertyBasics::getStatus, FormStatusConstant.FINISH));
        if (propertyBasics == null || StringUtil.isBlank(propertyBasics.getOrgId())){
            return null;
        }
        List<String> subtractChildList = new ArrayList<>();
        List<String> addChildList = new ArrayList<>();
        List<String> sumChildOrgIds = new ArrayList<>();

        IndicatorsValueDTO indicatorsValueDTO = new IndicatorsValueDTO();
        if (StringUtil.isBlank(reportTime)) {
            reportTime = newBulletinService.getMaxReportTimeByOrgId(propertyBasics.getOrgId());
        }
        handleOrgId(propertyBasics.getOrgId(), indicatorsValueDTO, subtractChildList, addChildList, sumChildOrgIds);
        String[] reportTimes = reportTime.split(StringPool.DASH);
        indicatorsValueDTO.setYear(reportTimes[0]);
        indicatorsValueDTO.setMonth(reportTimes[1]);
        indicatorsValueDTO.setCodes(Stream.of(KLJ1, KLJ19).collect(Collectors.toList()));
        List<IndicatorsValueVO> valueVOS = indicatorsValueMapper.queryAllMonthGroupValueByCode2(indicatorsValueDTO);
        //  对valueVOS按code分组，对value合计
        Map<String, BigDecimal> codeMonthValueMap = ZZDHelper
                .indicatorsValueToMonthValueMap(Integer.valueOf(reportTimes[0]), valueVOS, subtractChildList, addChildList, sumChildOrgIds);
        List<Integer> monthList = new ArrayList<>();
        List<BigDecimal> businessIncomeList = new ArrayList<>();
        List<BigDecimal> totalProfitList = new ArrayList<>();
        for (int i = 1; i <= Integer.valueOf(reportTimes[1]); i++) {
            monthList.add(i);
            businessIncomeList.add(BigDecimalUtil.divide(codeMonthValueMap.get(KLJ1 + StringPool.DASH + i), BigDecimal.valueOf(10000), 2, BigDecimal.ROUND_HALF_UP));
            totalProfitList.add(BigDecimalUtil.divide(codeMonthValueMap.get(KLJ19 + StringPool.DASH + i), BigDecimal.valueOf(10000), 2, BigDecimal.ROUND_HALF_UP));
        }
        return RevenueMonthDataVO.builder().monthList(monthList).businessIncomeList(businessIncomeList).totalProfitList(totalProfitList).build();
    }

}
